package com.ruoyi.wapp.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.base.BaseEntity;
import com.ruoyi.common.constant.CacheKeyConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ResultConstants;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.sms.wlwx.client.SmsClient;
import com.ruoyi.common.sms.wlwx.client.SmsClientMain;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.RandomStringUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.email.EmailUtil;
import com.ruoyi.system.domain.WdyUser;
import com.ruoyi.system.service.IWdyUserService;
import com.ruoyi.wapp.controller.base.BaseController;
import com.ruoyi.wapp.controller.base.Result;
import com.ruoyi.wapp.util.MyConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
import java.util.concurrent.TimeUnit;



@RestController
public class LoginController extends BaseController {


	@Autowired
	private IWdyUserService wdyUserService;

	@PostMapping(value = "/login")
	public Result login(String mobile, String password, HttpServletRequest request){
		//检查参数合法性
		if(StringUtils.isEmpty(mobile)) {
			return Result.error(ResultConstants.FI1000, "mobile" + MessageUtils.message("not.null"));
		}
		if(StringUtils.isEmpty(password)) {
			return Result.error(ResultConstants.FI1000, "password" + MessageUtils.message("not.null"));
		}

		QueryWrapper<WdyUser> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("user_name", mobile);
		queryWrapper.eq("del_flag", BaseEntity.NOT_DELETED);
		WdyUser user = wdyUserService.getOne(queryWrapper);
		if(user == null) {
			return Result.error(ResultConstants.EX9110, MessageUtils.message("user.password.not.match"));
		}

		BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
		if(!passwordEncoder.matches(password, user.getPassword())) {
			return Result.error(ResultConstants.EX9110, MessageUtils.message("user.password.not.match"));
		}

		String token = UUID.randomUUID().toString().replace("-", "");
		String tokenCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.TOKEN_TPL, token);
		redisTemplate.opsForValue().set(tokenCacheKey, user, MyConstants.CONFIG.SESSION_TIMEOUT, TimeUnit.SECONDS);

		Result result = Result.ok();
		result.put("token", token);
		result.put("user", user);
		return result;
	}

	@GetMapping(value = "/getLoginSmsCode")
	public Result getLoginSmsCode(String mobile)throws Exception {
		//检查参数合法性
		if(StringUtils.isEmpty(mobile)) {
			return Result.error(ResultConstants.FI1000, "mobile" + MessageUtils.message("not.null"));
		}
		if(!mobile.matches(Constants.MOBILE_PATTERN)) {
			return Result.error(ResultConstants.FI1000, MessageUtils.message("user.mobile.phone.number.not.valid"));
		}
		QueryWrapper<WdyUser> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("mobile_phone", mobile);
		queryWrapper.eq("del_flag", BaseEntity.NOT_DELETED);
		WdyUser user = wdyUserService.getOne(queryWrapper);
		if(user == null) {
			return Result.error(ResultConstants.FI2000, MessageUtils.message("user.not.exists"));
		}

		String smsCodeCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.SMS_CODE_TPL, mobile, MyConstants.SMS_CODE_TYPE.LOGIN);
		String smsCode = (String) redisTemplate.opsForValue().get(smsCodeCacheKey);
		if(StringUtils.isNotEmpty(smsCode)) {
			log.info("smsCode:{}", smsCode);
			return Result.error(ResultConstants.FI3002, MessageUtils.message("vcode.not.expired"));
		}
		//过期了,就再次发送短信

		smsCode = RandomStringUtils.getNumber(4);
		String content = String.format(MessageUtils.message("msg.content"), smsCode);
		SmsClient smsClient = new SmsClient();
		String resultMsg = SmsClientMain.getReportResultMsg(mobile, content);
		JSONObject jsonObject=JSONObject.parseObject(resultMsg);
		if ("0".equals(jsonObject.get("respCode"))) {
			redisTemplate.opsForValue().set(smsCodeCacheKey, smsCode, MyConstants.CONFIG.SMS_CODE_TIMEOUT, TimeUnit.SECONDS);
			log.info("smsCode:{}", smsCode);
			return Result.ok(MessageUtils.message("msg.send.success") + jsonObject.get("respMsg"));
		} else {
			/**
			 *  1000：服务器出现未知异常！
			 *  1001 操作不合法，操作前未获取Token，或Token已过时
			 *	1002 签名验证不通过！
			 *	1003 Json参数解析出错
			 *	1004 操作不合法，cust_code: xxxxxx不存在
			 *	1005 客户端IP鉴权不通过
			 *	1006 客户账号已停用！
			 *	1008 客户提交接口协议HTTPS, 与客户参数允许的协议不一致！
			 *	1009 提交的短信内容超过规定的长度！
			 *	1011 客户账户不存在！
			 *	1012 账户没有足够的余额
			 *	1013 扩展号码(sp_code)不符合规范！
			 */
			return Result.error(MyConstants.RESULT.FI1000,MessageUtils.message("msg.send.error"));
		}
	}

	@GetMapping(value = "/logout")
	public Result logout() {
		String tokenCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.TOKEN_TPL, super.getToken());
		redisTemplate.delete(tokenCacheKey);
		return Result.ok();
	}

	@GetMapping("/getResetNewPwdSmsCode")
	public Result getResetNewPwdSmsCode(String mobile) throws Exception{
		if(StringUtils.isEmpty(mobile)) {
			return Result.error(ResultConstants.FI1000, "mobile" + MessageUtils.message("not.null"));
		}
		if(!mobile.matches(Constants.MOBILE_PATTERN)) {
			return Result.error(ResultConstants.FI1000, MessageUtils.message("user.mobile.phone.number.not.valid"));
		}
		QueryWrapper<WdyUser> query = new QueryWrapper<>();
		query.eq("mobile_phone", mobile);
		query.eq("del_flag", BaseEntity.NOT_DELETED);
		WdyUser user = wdyUserService.getOne(query);
		if(user == null) {
			return Result.error(ResultConstants.EX9110, MessageUtils.message("user.not.exists"));
		}
		String smsCodeCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.SMS_CODE_TPL, mobile, MyConstants.SMS_CODE_TYPE.RESET_PWD);
		String smsCode = (String) redisTemplate.opsForValue().get(smsCodeCacheKey);
		if(StringUtils.isNotEmpty(smsCode)) {
			return Result.error(ResultConstants.FI3002, MessageUtils.message("vcode.not.expired"));
		}
		smsCode = RandomStringUtils.getNumber(4);
		String content = String.format(MessageUtils.message("msg.content"), smsCode);
		String resultMsg = SmsClientMain.getReportResultMsg(mobile, content);
		JSONObject jsonObject=JSONObject.parseObject(resultMsg);
		if ("0".equals(jsonObject.get("respCode"))) {
			redisTemplate.opsForValue().set(smsCodeCacheKey, smsCode, MyConstants.CONFIG.SMS_CODE_TIMEOUT, TimeUnit.SECONDS);
			log.info("smsCode:{}", smsCode);
			return Result.ok(MessageUtils.message("msg.send.success") + jsonObject.get("respMsg"));
		} else {
			/**
			 *  1000：服务器出现未知异常！
			 *  1001 操作不合法，操作前未获取Token，或Token已过时
			 *	1002 签名验证不通过！
			 *	1003 Json参数解析出错
			 *	1004 操作不合法，cust_code: xxxxxx不存在
			 *	1005 客户端IP鉴权不通过
			 *	1006 客户账号已停用！
			 *	1008 客户提交接口协议HTTPS, 与客户参数允许的协议不一致！
			 *	1009 提交的短信内容超过规定的长度！
			 *	1011 客户账户不存在！
			 *	1012 账户没有足够的余额
			 *	1013 扩展号码(sp_code)不符合规范！
			 */
			return Result.error("", "");
		}
	}


	/**
	 * 设置密码
	 * @param mobilePhone
	 * @param password 密码
	 * @param smsCode 短信验证码
	 * @return
	 */
	@PostMapping("/resetNewPwd")
	public Result resetNewPwd(String mobilePhone, String password, String smsCode) {
		if(StringUtils.isEmpty(mobilePhone)) {
			return Result.error(ResultConstants.FI1000, "mobilePhone" + MessageUtils.message("not.null"));
		}
		if(StringUtils.isEmpty(password)) {
			return Result.error(ResultConstants.FI1000, "password" + MessageUtils.message("not.null"));
		}
		if(!password.matches(Constants.PWD_PATTERN)) {
			throw new BusinessException(ResultConstants.FI1000, MessageUtils.message("user.password.not.valid"));
		}
		if(StringUtils.isEmpty(smsCode)) {
			return Result.error(ResultConstants.FI1000, "smsCode" + MessageUtils.message("not.null"));
		}
		String smsCodeCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.SMS_CODE_TPL, mobilePhone, MyConstants.SMS_CODE_TYPE.RESET_PWD);
		String cacheSmsCode = (String) redisTemplate.opsForValue().get(smsCodeCacheKey);
		if(isProdEnv() && cacheSmsCode == null) {
			throw new BusinessException(ResultConstants.FI3000, MessageUtils.message("vcode.expired"));
		}
		if(isProdEnv() && !cacheSmsCode.equals(smsCode)) {
			throw new BusinessException(ResultConstants.FI3001, MessageUtils.message("vcode.error"));
		}
		QueryWrapper<WdyUser> query = new QueryWrapper<>();
		query.eq("user_name", mobilePhone);
		query.eq("del_flag", BaseEntity.NOT_DELETED);
		WdyUser user = wdyUserService.getOne(query);
		BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
		setpwd(password, passwordEncoder, user);
		return Result.ok();
	}

	private void setpwd(String password, BCryptPasswordEncoder passwordEncoder, WdyUser user) {
		WdyUser updateUser = new WdyUser();
		updateUser.setPassword(passwordEncoder.encode(password));
		QueryWrapper<WdyUser> query = new QueryWrapper<>();
		query.eq("user_id", user.getUserId());
		query.eq("del_flag", BaseEntity.NOT_DELETED);
		wdyUserService.update(updateUser, query);
	}

	/**
	 * 是否有注册过
	 * @param mobile
	 * @return
	 */
	@RequestMapping(value = "/getRegisterUser", method = RequestMethod.GET)
	public Result getRegisterUser(String mobile) {
		QueryWrapper<WdyUser> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("user_name", mobile);
		queryWrapper.eq("del_flag", BaseEntity.NOT_DELETED);
		WdyUser user = wdyUserService.getOne(queryWrapper);
		if(user!=null){
			return Result.ok().put("register", true);
		}else {
			return Result.ok().put("register", false);
		}

	}

	@GetMapping("/getResetNewPwdEmailCode")
	public Result getResetNewPwdEmailCode(String email) throws Exception{
		if(StringUtils.isEmpty(email)) {
			return Result.error(ResultConstants.FI1000, "email" + MessageUtils.message("not.null"));
		}
		if(!email.matches(Constants.EMAIL_PATTERN)) {
			return Result.error(ResultConstants.FI1000, MessageUtils.message("user.mobile.phone.number.not.valid"));
		}
		QueryWrapper<WdyUser> query = new QueryWrapper<>();
		query.eq("user_name", email);
		query.eq("del_flag", BaseEntity.NOT_DELETED);
		WdyUser user = wdyUserService.getOne(query);
		if(user == null) {
			return Result.error(ResultConstants.EX9110, MessageUtils.message("user.not.exists"));
		}
		String smsCodeCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.SMS_CODE_TPL, email, MyConstants.SMS_CODE_TYPE.RESET_PWD);
		String smsCode = (String) redisTemplate.opsForValue().get(smsCodeCacheKey);
		if(StringUtils.isNotEmpty(smsCode)) {
			return Result.error(ResultConstants.FI3002, MessageUtils.message("vcode.not.expired"));
		}
		smsCode = RandomStringUtils.getNumber(4);
		try {
			String content = String.format(MessageUtils.message("msg.content"), smsCode);
			String result = EmailUtil.sendFromYandex(email, MessageUtils.message("msg.title"), content);
			if (!"SUCCESS".equals(result)){
				return Result.error(ResultConstants.FI3005,MessageUtils.message("msg.send.error"));
			}
			redisTemplate.opsForValue().set(smsCodeCacheKey, smsCode, MyConstants.CONFIG.SMS_CODE_TIMEOUT, TimeUnit.SECONDS);
			return Result.ok();
		} catch (Exception e) {
			log.error("发送注册验证码错误", e);
			return Result.error(ResultConstants.FI3005,MessageUtils.message("msg.send.error"));
		}

	}
}
